package com.pingsky.apm.agent.core.service;

import com.pingsky.apm.agent.api.log.PLogger;
import com.pingsky.apm.agent.api.log.PLoggerFactory;
import com.pingsky.apm.agent.api.service.BootService;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.ServiceLoader;

public enum ServiceManager {
    INSTANCE;

    private Map<Class, BootService> bootedServices = Collections.emptyMap();

    private PLogger logger = PLoggerFactory.getLogger(ServiceManager.class);

    public <T extends BootService> T findService(Class<T> serviceClass) {
        return (T) bootedServices.get(serviceClass);
    }

    public void boot() {
        bootedServices = loadAllServices();

        start();

    }

    private Map<Class, BootService> loadAllServices() {
        Map<Class, BootService> bootedServices = new LinkedHashMap<Class, BootService>();
        load(bootedServices);
        return bootedServices;
    }

    void load(Map<Class, BootService> bootedServices) {
        for (final BootService bootService : ServiceLoader.load(BootService.class, ServiceManager.class.getClassLoader())) {
            bootedServices.put(bootedServices.getClass(), bootService);
        }
    }

    private void start() {
        for (BootService service : bootedServices.values()) {
            try {
                service.start();
            } catch (Throwable e) {
                logger.error("ServiceManager try to start {} fail.", service.getClass().getName());
            }
        }
    }
}
